﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEngine.Networking;
using System;
using UnityEngine.Events;//使用Unity的事件系统
public class AssetUpdater : MonoBehaviour
{
    public string remoteDir;//远程路径
    private string saveDir;// //本地保存AB包的路径
    private string localFIleListPath;//本地清单路径
    private string remoteFieListText;//远程清单内容
    private string localFIleListText;//本地清单内容
    public ProgressEvent onAllProgress;
    public ProgressEvent onCurrentProgress;
    private string[] urls;//需要下载的文件url列表,在对比完本地和远程清单后生成的
    private int downloadCount = 0;
    private UnityWebRequest currentRequest;
    private void OnEnable()
    {
        FileHelper.CreatDirBeforeWrite(Application.persistentDataPath);
        saveDir = Path.Combine(Application.persistentDataPath, "AB/");
        localFIleListPath = Path.Combine(saveDir, "FileList.txt");
        StartCheckFileList();
    }
    private void StartCheckFileList()
    {
        //下载清单
        var downloader = Downloader.Download(Path.Combine(remoteDir, "FileList.txt"));
        downloader.OnStartAll += P => { print("开始下载清单文件"); };
        downloader.OnFinishOne += OnFileListDown;
    }

    //当清单文件被下载下来
    private void OnFileListDown(UnityWebRequest fileListReq)
    {
        //取得远程清单
        remoteFieListText = fileListReq.downloadHandler.text;
        //读取本地清单,如果不存在就返回空字符串
        if (!File.Exists(localFIleListPath))
            localFIleListText = "";
        else
            localFIleListText = File.ReadAllText(localFIleListPath);
        string[] remotelines = remoteFieListText.Split('\n');
        string[] localLines = localFIleListText.Split('\n');

        Dictionary<string, string> remoteDic = CreatDirectory(remotelines);
        Dictionary<string, string> localDic = CreatDirectory(localLines);

        //对比
        var result = CompareDictionary(remoteDic, localDic);
        //构造下载列表
        urls = new string[result.onglyA.Count + result.difference.Count];
        int index = 0;
        foreach (var item in result.onglyA)
        {
            urls[index++] = Path.Combine(remoteDir, item);
        }
        foreach (var item in result.onglyB)
        {
            //处理新版版本已经不需要的文件
        }
        foreach (var item in result.difference)
        {
            urls[index++] = Path.Combine(remoteDir, item);
        }

        //开始下载每个文件
        Downloader downloader = Downloader.Download(urls);
        downloader.OnStartOne += OnStartOne;
        downloader.OnFinishOne += OnFinishOne;
        downloader.OnFinishAll += OnFinishAll;
    }

    public static Dictionary<string, string> CreatDirectory(string[] lines)
    {
        var dic = new Dictionary<string, string>();
        for (int i = 0; i < lines.Length; i++)
        {
            string line = lines[i];
            if (string.IsNullOrWhiteSpace(line)) continue;
            int n = line.IndexOf('\t');
            string key = line.Substring(0, n);
            string value = line.Substring(n + 1, line.Length - n - 1);
            dic.Add(key, value);
        }
        return dic;
    }

    private void OnStartOne(UnityWebRequest req)
    {
        currentRequest = req;
        Debug.Log("开始下载:" + req.url.Replace(remoteDir, ""));
    }

    private void OnFinishAll(Downloader req)
    {
        print("全部下载完成");
        File.WriteAllText(localFIleListPath, remoteFieListText);
        onAllProgress?.Invoke(1);
    }

    //当下载完成一个文件
    private void OnFinishOne(UnityWebRequest fileReq)
    {
        print("下载完成:" + fileReq.uri);
        //取出相对路径
        string relativePath = fileReq.url.Replace(remoteDir, "");
        //构造完整写入路径
        string writePath = Path.Combine(saveDir, relativePath);
        //确保写入目录存在
        FileHelper.CreatDirBeforeWrite(writePath);
        File.WriteAllBytes(writePath, fileReq.downloadHandler.data);

        onAllProgress?.Invoke(++downloadCount / (float)urls.Length);
    }

    //对比两个字典返回对比结果: 仅A 仅B 不同
    public static CompareDictionaryReslult CompareDictionary(Dictionary<string, string> a, Dictionary<string, string> b)
    {
        CompareDictionaryReslult result = new CompareDictionaryReslult();
        result.onglyB.AddRange(b.Keys);//所有b 的key
        foreach (var item in a.Keys)
        {
            if (b.ContainsKey(item))
            {
                result.onglyB.Remove(item);//b 的key 中移除a的key
                if (a[item] != b[item])
                {
                    result.difference.Add(item);//添加不一样的
                }
            }
            else
            {
                result.onglyA.Add(item);//添加仅A的
            }
        }
        return result;
    }

    private void Update()
    {
        if (currentRequest != null)
        {
            onCurrentProgress?.Invoke(currentRequest.downloadProgress);
        }
    }

    #region 内部类

    [System.Serializable]
    public class ProgressEvent : UnityEvent<float>
    {
    }

    public class CompareDictionaryReslult
    {
        public List<string> onglyA = new List<string>();
        public List<string> onglyB = new List<string>();
        public List<string> difference = new List<string>();
    }
    #endregion 内部类
}